package ar.uba.is2.sc.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;

import ar.uba.is2.common.Const;
import ar.uba.is2.common.config.AbstractConfiguracion;
import ar.uba.is2.common.loc.Coordenada;
import ar.uba.is2.common.mensaje.Componente;
import ar.uba.is2.common.mensaje.Receptor;
import ar.uba.is2.common.mensaje.canal.Canal;
import ar.uba.is2.common.mensaje.canal.impl.CanalImpl;
import ar.uba.is2.common.mensaje.protocolo.Protocolo;
import ar.uba.is2.common.mensaje.protocolo.impl.ProtocoloSimple;
import ar.uba.is2.common.mensaje.puerto.impl.PuertoArchivoFactory;
import ar.uba.is2.sc.comm.ReceptorSuscripciones;
import ar.uba.is2.sc.ecmanager.EcData;

public class Configuracion extends AbstractConfiguracion {

	private static final Logger logger = Logger.getLogger(Configuracion.class);
	
	private static final String LOG4J_FILENAME = "log4j-sc.properties";
	
	private static final String archivoConfiguracion = "sc.properties";
	
	@Override
	protected void doInit() {
		 
		configurarContexto();
		
		configurarEcs();
		
		Protocolo protocolo = configurarProtocolo();
		 
		Contexto.instance.setProtocolo(protocolo);
	}

	private void configurarEcs() {

		String string = Contexto.instance.get("estaciones.centrales.nombres");
		String[] ecIds = string.split(",");
		
		Map<Coordenada, EcData> ecs = new HashMap<Coordenada, EcData>();
		
		for (String ecId : ecIds) {
			EcData ec = new EcData();
			ec.setComponenteEc(new Componente(ecId));
			
			String stringCoord = Contexto.instance.get(String.format("estaciones.centrales.%s",ecId));
			
			String[] coord = stringCoord.split(",");
			double latitud = Double.parseDouble(coord[0]);
			double longitud = Double.parseDouble(coord[1]);
			
			ec.setCoordenada(new Coordenada(latitud, longitud));
			
			ecs.put(ec.getCoordenada(), ec);
		}
		
		Contexto.instance.setEstacionesCentrales(ecs);
	}

	private void configurarContexto() {
		try {
			logger.info("Levantando propiedades");
			Contexto contexto = new Contexto();
			
			Properties propiedades = new Properties();
			propiedades.load(ClassLoader.getSystemResourceAsStream(archivoConfiguracion));
			contexto.setPropiedades(propiedades);
			
			Contexto.instance = contexto;
			
		} catch (Exception e) {
			throw new RuntimeException("No se pudo terminar la configuracion", e);
		}
	}

	@Override
	protected String getLoggingFilename() {
		return LOG4J_FILENAME;
	}

	
	private Protocolo configurarProtocolo() {
		logger.info("Creando protocolo");
		ProtocoloSimple protocolo = new ProtocoloSimple();
		
		Canal canalDeComunicacion = crearCanal(protocolo);
		
		protocolo.setCanal(canalDeComunicacion);
		
		protocolo.registrarReceptor(new ReceptorSuscripciones());
		
		return protocolo;
	}

	private Canal crearCanal(Receptor receptor) {
		logger.info("Creando canales de comunicacion");
		CanalImpl canal = new CanalImpl();
		canal.setPuertoFactory(new PuertoArchivoFactory("SC"));
		canal.suscribirEntrada(Const.COMPONENTE_SERVIDOR_CENTRAL, receptor);
		
		for (EcData ec : Contexto.instance.getEstacionesCentrales().values()) {
			canal.suscribirSalida(ec.getComponenteEc());
		}
		
		return canal;
	}
}
